from djongo.models import ListField
from django.utils.dateparse import parse_date
from rest_framework import serializers

from mongolog.utils import date_range, res_queryset_id2name
from mongolog.models import CASLog


def asset_heat_serializer(model, field, top=5, **filters):
    """资产热度图，每项资产前n名"""
    # 对于有索引的字段，$exists会先做IXSCAN找出所有索引，再根据索引做FETCH，
    # 这非常影响性能，为了提高查询速度这里注释掉
    # 对于不存在的字段，实际上并不会被归入$sortByCount中
    # match = {field: {'$exists': True, '$ne': ''}}
    aggregate = [
        {'$sortByCount': f'${field}'},
        {'$limit': top}
    ]
    if filters:
        aggregate.insert(0, {'$match': filters})
    if isinstance(model._meta.get_field(field), ListField):
        aggregate.insert(0, {'$unwind': f'${field}'})

    queryset = model.objects.mongo_aggregate(aggregate)
    if model == CASLog and field == 'resource':
        queryset = res_queryset_id2name(queryset)

    return [{'name': agg['_id'], 'count': agg['count']} for agg in queryset]


def asset_trend_serializer(model, date_from=None, date_to=None, **filters):
    """资产趋势图，每项资产的模板"""
    aggregation = [
        {
            '$group': {
                '_id': '$date',
                'count': {'$sum': 1}
            }
        }
    ]
    match = date_range('log_time', date_from, date_to)
    if filters:
        match.update(filters)
    if match:
        aggregation.insert(0, {'$match': match})
    queryset = model.objects.mongo_aggregate(aggregation)

    trend = {parse_date(agg['_id']): agg['count'] for agg in queryset if agg.get('_id')}
    return trend


class TerminalMalwareTrendSerializer(serializers.Serializer):
    date = serializers.DateField()
    danger = serializers.IntegerField()
    risk = serializers.IntegerField()
    sensitive = serializers.IntegerField()